package com.hollis公众号.逃逸分析;

public class Test {

	//逃逸分析的基本行为就是分析对象动态作用域：当一个对象在方法中被定义后，它可能被外部方法所引用，例如作为调用参数传递到其他地方中，称为方法逃逸。
	//第一段代码中的sb就逃逸了，而第二段代码中的sb就没有逃逸。
	//在Java代码运行时，通过JVM参数可指定是否开启逃逸分析，
	//-XX:+DoEscapeAnalysis ： 表示开启逃逸分析
	//-XX:-DoEscapeAnalysis ： 表示关闭逃逸分析 从jdk 1.7开始已经默认开始逃逸分析，如需关闭，需要指定-XX:-DoEscapeAnalysis
	public static StringBuffer craeteStringBuffer(String s1, String s2) {
	    StringBuffer sb = new StringBuffer();
	    sb.append(s1);
	    sb.append(s2);
	    return sb;
	}

	public static String createStringBuffer(String s1, String s2) {
	    StringBuffer sb = new StringBuffer();
	    sb.append(s1);
	    sb.append(s2);
	    return sb.toString();
	}

	/**
	 * 使用逃逸分析，编译器可以对代码做如下优化：
	 * 同步省略：demo1
	 * 标量替换：demo2
	 * 栈上分配：
	 * 在Java虚拟机中，对象是在Java堆中分配内存的，这是一个普遍的常识。但是，有一种特殊情况，那就是如果经过逃逸分析后发现，一个对象并没有逃逸出方法的话，那么就可能被优化成栈上分配。这样就无需在堆上分配内存，也无须进行垃圾回收了。
	 * 这里，还是要简单说一下，其实在现有的虚拟机中，并没有真正的实现栈上分配，在对象并不一定都是在堆上分配内存的中我们的例子中，对象没有在堆上分配，其实是标量替换实现的。
	 *
	 * 所以，如果以后再有人问你：是不是所有的对象和数组都会在堆内存分配空间？
	 * 那么你可以告诉他：不一定，随着JIT编译器的发展，在编译期间，如果JIT经过逃逸分析，发现有些对象没有逃逸出方法，那么有可能堆内存分配会被优化成栈内存分配。但是这也并不是绝对的。就像我们前面看到的一样，在开启逃逸分析之后，也并不是所有User对象都没有在堆上分配。
	 */

}
